package com.lst.projectlib.component.ListView;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class StickyHeaderListView extends XPinnedHeaderListView {

	private View mHeader;
    private View mContent;

    private int mHeaderHeight;
    private int mOriginalHeaderTop;
    private int mOriginalContentTop;
    private int mHeaderTop;
    private int mContentTop;

    private int mStatus = STATUS_EXPANDED;
    public static final int STATUS_EXPANDED = 1;
    public static final int STATUS_COLLAPSED = 2;

//    private int mTouchSlop;

    private int mLastY = 0;

    private boolean mInitDataSucceed = false;
    
	public StickyHeaderListView(Context context) {
		super(context);
	}

	public StickyHeaderListView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public StickyHeaderListView(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
	}
    
    public void setStickyView(View headerView) {
    	mHeader = headerView;
    	mContent = this;
    }
    
    private void initData() {
		mHeaderHeight = mHeader.getMeasuredHeight();
		mHeaderTop = mOriginalHeaderTop = mHeader.getTop();
		mContentTop = mOriginalContentTop = mContent.getTop();
//		mTouchSlop = ViewConfiguration.get(getContent()).getScaledTouchSlop();
		if (mHeaderHeight > 0) {
			mInitDataSucceed = true;
		}
		
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    	int intercepted = 0;
        int y = (int) event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {
            mLastY = y;
            intercepted = 1;
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            float deltaY = y - mLastY;
            
            // 如果listview本身已经有滚动了，需要等到滚动到第一条才能执行整体滚动
            if (getFirstVisiblePosition() != 0 && deltaY > 0) {
            	intercepted = 0;
            	// 只有在这种条件下才存上次的y值，else中的条件因为可能满足改变listview的位置，
            	// 会导致event.getY()的值并不是原始值，而是位置变化后的原始值
            	mLastY = y;
            } else {
    			// 跟随手指滑动
                intercepted = scrollByDeltaY(deltaY);
            }
            
            break;
        }
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
        {
        	intercepted = 0;
            mLastY = 0;
        	int destTop = 0;
        	
    		// 如果listview本身已经有滚动了，需要等到滚动到第一条才能执行整体滚动
    		if (getFirstVisiblePosition() == 0) {
            	// 如果当前位置已经超过头部View的高度的一半的时候，
            	// 则自动平滑的滚动到隐藏头部view的位置
                if (Math.abs(mHeaderTop) > mHeaderHeight * 0.5) {
                	destTop = -mHeaderHeight;
                    mStatus = STATUS_COLLAPSED;
                } else {
                	// 否则则滚动到全部显示的位置
                	destTop = mOriginalHeaderTop;
                    mStatus = STATUS_EXPANDED;
                }
                
                this.smoothScrollByDeltaY(destTop, 500);
    		}
            break;
        }
        default:
            break;
        }
        
        return intercepted != 0 ? true : super.onTouchEvent(event);
    }
    
    /**
     * 滚动一定的距离
     */
    private int scrollByDeltaY (float deltaY) {
    	int intercepted = 0;
        if (!mInitDataSucceed) {
            initData();
        }
        
    	// 即将滑动到的位置
        int headerTop, contentTop, headerBottom, contentBottom;
        
    	// 如果已经滑动到完全隐藏头部view的位置的时候，就不再滑动(向上滑动)
//        if (mHeader.getTop() + deltaY <= -mHeaderHeight) {
    	if (mContentTop + deltaY <= mOriginalContentTop - mHeaderHeight || mHeaderTop + deltaY <= -mHeaderHeight) {
    		headerTop = mOriginalHeaderTop - mHeaderHeight;
    		contentTop = mOriginalContentTop - mHeaderHeight;
    		headerBottom = mOriginalHeaderTop;
    		contentBottom = (int) (mContent.getBottom());
    		mStatus = STATUS_COLLAPSED;
    		
    	} else if (mContentTop + deltaY >= mOriginalContentTop || mHeaderTop + deltaY >= mOriginalHeaderTop) {
//    		if (mHeader.getTop() + deltaY >= mOriginalHeaderTop) {
    		// 如果已经滑动到完全显示头部view的位置的时候，就不再滑动(向下滑动)
    		headerTop = mOriginalHeaderTop;
    		contentTop = mOriginalContentTop;
    		headerBottom = mOriginalHeaderTop + mHeaderHeight;
    		contentBottom = (int) (mContent.getBottom());
    		mStatus = STATUS_EXPANDED;
    		
    	} else {
    		headerTop = (int) (mHeaderTop + deltaY);
    		contentTop = (int) (mContentTop + deltaY);
    		headerBottom = (int) (mHeaderTop + mHeaderHeight + deltaY);
    		contentBottom = (int) (mContent.getBottom());
    		mStatus = STATUS_EXPANDED;
    		intercepted = 1;
    	}
        
    	// 存储下来当前滚动到的top
    	mHeaderTop = headerTop;
    	mContentTop = contentTop;
    	
    	// 更改头部View的位置
		mHeader.layout(mHeader.getLeft(), headerTop,
				mHeader.getRight(), headerBottom);
		
		// 更改内容View的位置
		mContent.layout(mContent.getLeft(), contentTop,
				mContent.getRight(), contentBottom);
		
		
		return intercepted;
    }
    
    /**
     * 平滑的滚动到相应位置
     * @param destTop
     * @param duration
     */
    private void smoothScrollByDeltaY (final int destTop, long duration) {
    	// 即将需要滑动的距离
    	int position = destTop - mHeaderTop;
    	// 计算需要的帧数
    	final int frameCount = (int) (duration / 1000f * 30) + 1;
    	// 每帧需要滚动的单位距离
        final float partation = position / (float) frameCount;
    	// 逐帧播放
    	new Thread("Thread#smoothScrollByDeltaY") {
            @Override
            public void run() {
                for (int i = 0; i < frameCount; i++) {
                    post(new Runnable() {
                        public void run() {
                        	if (mHeader != null) {
                        		// 如果是这种情况代表画面自动刷新成原样了，
                        		// 需要做处理给改回来
//                        		if ((mHeader.getTop() >= mOriginalHeaderTop && mStatus == STATUS_COLLAPSED) ||
//                        				(mHeader.getTop() <= -mHeaderHeight && mStatus == STATUS_EXPANDED)) {
//                        			scrollByDeltaY(destTop);
//                        			return;
//                        		}
                        	}
                        	scrollByDeltaY(partation);
                        }
                    });
                    try {
                        sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };

        }.start();
    }
//    
//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//    	int height = MeasureSpec.makeMeasureSpec(this.getBottom() - mContentTop, MeasureSpec.EXACTLY);
//    	super.onMeasure(widthMeasureSpec, height);
//    }
//    
    @Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
//		int destTop;
//		if (mStatus == STATUS_COLLAPSED) {
//			destTop = -mHeaderHeight;
//		} else {
//			destTop = mOriginalHeaderTop;
//		}
//		// 如果是这种情况代表画面自动刷新成原样了，
//		// 需要做处理给改回来
//		if (mHeader != null) {
//			if ((mHeader.getTop() >= mOriginalHeaderTop && mStatus == STATUS_COLLAPSED)
//					|| (mHeader.getTop() <= -mHeaderHeight && mStatus == STATUS_EXPANDED)) {
//				scrollByDeltaY(destTop);
//			}
//		}
        if (!mInitDataSucceed) {
            initData();
            
            // 初期让其成关闭状态
            mStatus = STATUS_COLLAPSED;
			if (mHeader != null) {
				scrollByDeltaY(-mHeaderHeight);
			}
        }
        
		// 用来记录top的变化，因为不知什么原因，在滑动过程中，布局会重新初始化，
	    // 导致这些成员变量的值会被回收，重新初始化。用来监测是否发生变化
		if (mContentTop != t) {
			// 更改头部View的位置
			mHeader.layout(mHeader.getLeft(), mHeaderTop,
					mHeader.getRight(), mHeaderTop + mHeaderHeight);
			
			// 更改内容View的位置
			mContent.layout(l, mContentTop, r, b);
		} else {
			super.onLayout(changed, l, t, r, b);
		}
	}
}
